/*
========================================================================
 Name        : SingaporeBusAppUi.cpp
 Author      : 
 Copyright   : Your copyright notice
 Description : 
========================================================================
*/
// [[[ begin generated region: do not modify [Generated System Includes]
#include <eikmenub.h>
#include <akncontext.h>
#include <akntitle.h>
#include <aknquerydialog.h>
#include <aknlistquerydialog.h>
#include <akniconarray.h>
// ]]] end generated region [Generated System Includes]

// [[[ begin generated region: do not modify [Generated User Includes]
#include "SingaporeBusAppUi.h"
#include "SingaporeBus.hrh"
#include "PublicTransportMapContainer.hrh"
#include "SingaporeBusSettingItemList.hrh"
#include "SingaporeBusAccessPointsPriorityListBox.hrh"
#include "PublicTransportMapContainerView.h"
#include "SingaporeBusSettingItemListView.h"
#include "SingaporeBusAccessPointsPriorityListBoxView.h"
// ]]] end generated region [Generated User Includes]
#include "FunTrace.h"
#include "CSingaporeBusServicesView.h"
#include "CSingaporeBusStopsView.h"
#include "CSingaporeBusServicesArrivalTimeView.h"
#include "CSingaporeBusServiceRouteView.h"
#include "CSingaporeBusRouteView.h"
#include "CSingaporeBusFavoritesView.h"
#include <SingaporeBus.rsg>
#include <eikapp.h>
#include "CSingaporeBusGenericView.hrh"

// [[[ begin generated region: do not modify [Generated Constants]
// ]]] end generated region [Generated Constants]

/**
 * Construct the CSingaporeBusAppUi instance
 */ 
CSingaporeBusAppUi::CSingaporeBusAppUi() : iListTabDecorator(NULL), iRouteTabDecorator(NULL)
	{
	// [[[ begin generated region: do not modify [Generated Contents]
	// ]]] end generated region [Generated Contents]
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	iAknSplitInputEnabled = EFalse;
	}

/** 
 * The appui's destructor removes the container from the control
 * stack and destroys it.
 */
CSingaporeBusAppUi::~CSingaporeBusAppUi()
	{
	// [[[ begin generated region: do not modify [Generated Contents]
	// ]]] end generated region [Generated Contents]
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	iTabCallback->Cancel();
	HideTabGroup();
	RArray<CBackViewQueueItem*>* toDelete[] = { &iBackViewQueue, &iListTabViewArray, &iRouteTabViewArray, &iFavoritesTabViewArray };
	for(TInt i = 0 ; i < sizeof(toDelete)/sizeof(toDelete[0]) ; ++i)
		{
		for(TInt j = 0 ; j < toDelete[i]->Count() ; ++j)
			delete (*toDelete[i])[j];
		toDelete[i]->Close();
		}
	
	}

// [[[ begin generated function: do not modify
void CSingaporeBusAppUi::InitializeContainersL()
	{
	iPublicTransportMapContainerView = CPublicTransportMapContainerView::NewL();
	AddViewL( iPublicTransportMapContainerView );
	SetDefaultViewL( *iPublicTransportMapContainerView );
	iSingaporeBusSettingItemListView = CSingaporeBusSettingItemListView::NewL();
	AddViewL( iSingaporeBusSettingItemListView );
	iSingaporeBusAccessPointsPriorityListBoxView = CSingaporeBusAccessPointsPriorityListBoxView::NewL();
	AddViewL( iSingaporeBusAccessPointsPriorityListBoxView );
	}
// ]]] end generated function

void CSingaporeBusAppUi::PushBackViewL(TUid aViewId, TUid aCustomMessageId, CBase* aCustomInfo)
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	CBackViewQueueItem* item = new (ELeave) CBackViewQueueItem;
	CleanupStack::PushL(item);
	item->iViewId = aViewId;
	item->iCustomMessageId = aCustomMessageId;
	item->iCustomInfo = aCustomInfo;
	iBackViewQueue.AppendL(item);
	CleanupStack::Pop(item);
	}


void CSingaporeBusAppUi::ShowListTabGroup(TInt aActive)
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	CAknTabGroup* tabGroup = NULL;
	if(!iListTabDecorator)
		{
		HideTabGroup();
		CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();
		CAknNavigationControlContainer* naviPane = (CAknNavigationControlContainer*)StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) );
		CAknTitlePane* titlePane = (CAknTitlePane*)StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) );
		iListTabDecorator = naviPane->CreateTabGroupL();
		tabGroup = ( CAknTabGroup* ) iListTabDecorator->DecoratedControl();
		// Set tab width
		if(doc->iFavoritesTitles.Count() >= 2)
			tabGroup->SetTabFixedWidthL ( EAknTabWidthWithFourTabs );
		else if(doc->iFavoritesTitles.Count() >= 1)
			tabGroup->SetTabFixedWidthL ( EAknTabWidthWithThreeTabs );
		else 
			tabGroup->SetTabFixedWidthL ( EAknTabWidthWithTwoTabs );
		// Add tabs to tab group
		{
		LCleanedupPtr<CAknIconArray> iconArray ( new (ELeave) CAknIconArray(5) );
		iconArray->ConstructFromResourceL(R_SINGAPORE_BUS_LIST_TAB_ICONS);
		tabGroup->AddTabL(0, ((*iconArray)[0])->Bitmap(), ((*iconArray)[0])->Mask());
		((*iconArray)[0])->SetBitmapsOwnedExternally(ETrue); // AddTabL takes ownership
		tabGroup->AddTabL(1, ((*iconArray)[1])->Bitmap(), ((*iconArray)[1])->Mask());
		((*iconArray)[1])->SetBitmapsOwnedExternally(ETrue); // AddTabL takes ownership
		}

		//tabGroup->AddTabL(0,_L("Stops") );
		//tabGroup->AddTabL(1,_L("Services") );
		for(TInt i = 0 ; i < doc->iFavoritesTitles.Count() ; ++i)
			{
			LCleanedupPtr<CAknIconArray> iconArray ( new (ELeave) CAknIconArray(5) );
			iconArray->ConstructFromResourceL(R_SINGAPORE_BUS_LIST_TAB_ICONS);
			tabGroup->AddTabL(i+2, ((*iconArray)[2])->Bitmap(), ((*iconArray)[2])->Mask());
			((*iconArray)[2])->SetBitmapsOwnedExternally(ETrue); // AddTabL takes ownership
			}
		tabGroup->SetObserver( this );	
		naviPane->PushL(*iListTabDecorator);
		}
	else
		tabGroup = ( CAknTabGroup* ) iListTabDecorator->DecoratedControl();
	if(aActive < tabGroup->TabCount())
		tabGroup->SetActiveTabByIndex(aActive);
	else
		tabGroup->SetActiveTabByIndex(0);
	}
void CSingaporeBusAppUi::ShowRouteTabGroup(TInt aActive)
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	CAknTabGroup* tabGroup = NULL;
	if(!iRouteTabDecorator)
		{
		HideTabGroup();
		CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();
		CAknNavigationControlContainer* naviPane = (CAknNavigationControlContainer*)StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) );
		CAknTitlePane* titlePane = (CAknTitlePane*)StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) );
		iRouteTabDecorator = naviPane->CreateTabGroupL();
		
		tabGroup = ( CAknTabGroup* ) iRouteTabDecorator->DecoratedControl();
		// Set tab width
		if(doc->iJourneyPlannerOutput->iItineraries.Count() >= 2)
			tabGroup->SetTabFixedWidthL ( EAknTabWidthWithFourTabs );
		else if(doc->iJourneyPlannerOutput->iItineraries.Count() >= 1)
			tabGroup->SetTabFixedWidthL ( EAknTabWidthWithThreeTabs );
		else 
			tabGroup->SetTabFixedWidthL ( EAknTabWidthWithTwoTabs );
		// Add tabs to tab group
		if(doc->iJourneyPlannerOutput)
			{
			for(TInt i = 0 ; i < doc->iJourneyPlannerOutput->iItineraries.Count() ; ++i)
				{
				
				LCleanedupPtr<CAknIconArray> iconArray ( new (ELeave) CAknIconArray(5) );
				iconArray->ConstructFromResourceL(R_SINGAPORE_BUS_ROUTE_TAB_ICONS);
				CFbsBitmap* bitmap = ((*iconArray)[0])->Bitmap();
				CFbsBitmap* mask = ((*iconArray)[0])->Mask();
				tabGroup->AddTabL(i, bitmap, mask);
				((*iconArray)[0])->SetBitmapsOwnedExternally(ETrue); // AddTabL takes ownership
				
				/*TBuf<128> buf;
				buf.Format(_L("Solution %d"), i+1);
				tabGroup->AddTabL(i, buf);*/
				}
			}
		tabGroup->SetObserver( this );	
		naviPane->PushL(*iRouteTabDecorator);
		}
	else
		tabGroup = ( CAknTabGroup* ) iRouteTabDecorator->DecoratedControl();
	if(aActive < tabGroup->TabCount())
		tabGroup->SetActiveTabByIndex(aActive);
	else
		tabGroup->SetActiveTabByIndex(0);
	}

void CSingaporeBusAppUi::HideTabGroup()
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	if(iRouteTabDecorator || iListTabDecorator)
		{
		CAknNavigationControlContainer* naviPane = (CAknNavigationControlContainer*)StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) );
		naviPane->Pop();
		delete iRouteTabDecorator;
		iRouteTabDecorator = NULL;
		delete iListTabDecorator;
		iListTabDecorator = NULL;
		}
	}
void CSingaporeBusAppUi::TabChangedL( TInt aIndex )
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);

	
	{
	TVwsViewId viewId;
	GetActiveViewId(viewId);
	RArray<CBackViewQueueItem*>* tabViewArray = NULL;
	TInt tabViewIndex = 0;
	CStoreViewState* storeView = NULL;
	TBool viewActivated = EFalse;
	switch(viewId.iViewUid.iUid)
		{
			case ESingaporeBusStopsViewId:
				tabViewIndex = 0;
				tabViewArray = &iListTabViewArray;
				storeView = (CSingaporeBusStopsView*)View(viewId.iViewUid);
				viewActivated = (((CSingaporeBusStopsView*)View(viewId.iViewUid))->iContainer.Get() != NULL);
				break;
			case ESingaporeBusServicesViewId:
				tabViewIndex = 1;
				tabViewArray = &iListTabViewArray;
				storeView = (CSingaporeBusServicesView*)View(viewId.iViewUid);
				viewActivated = (((CSingaporeBusServicesView*)View(viewId.iViewUid))->iContainer.Get() != NULL);
				break;
			case ESingaporeBusFavoritesViewId:
			case ESingaporeBusFavoritesViewId2:
				tabViewIndex = ((CSingaporeBusFavoritesView*)View(viewId.iViewUid))->iCurrentFavorite;
				tabViewArray = &iFavoritesTabViewArray;
				storeView = (CSingaporeBusFavoritesView*)View(viewId.iViewUid);
				viewActivated = (((CSingaporeBusFavoritesView*)View(viewId.iViewUid))->iContainer.Get() != NULL);
				break;
			case ESingaporeBusRouteViewId:
			case ESingaporeBusRouteViewId2:
				tabViewIndex = ((CSingaporeBusRouteView*)View(viewId.iViewUid))->iCurrentItinerary;
				tabViewArray = &iRouteTabViewArray;
				storeView = (CSingaporeBusRouteView*)View(viewId.iViewUid);
				viewActivated = (((CSingaporeBusRouteView*)View(viewId.iViewUid))->iContainer.Get() != NULL);
				break;
			default:
				break;
		}
	if(tabViewArray && viewActivated)
		{
		while(tabViewArray->Count() <= tabViewIndex)
			tabViewArray->AppendL(NULL);
		TBuf8<1024> buf;
		storeView->StoreViewStateL(buf);
		LCleanedupPtr<CBackViewQueueItem> item ( new (ELeave) CBackViewQueueItem );
		item->iViewId = viewId.iViewUid;
		item->iCustomMessageId = TUid::Uid(0);
		item->iCustomInfo = NULL;
		item->iCustomMessage = buf.AllocL();
		delete (*tabViewArray)[tabViewIndex];
		(*tabViewArray)[tabViewIndex] = item.Unmanage();
		}
	}
	
	
	if(iRouteTabDecorator)
		{
		TVwsViewId viewId;
		GetActiveViewId(viewId);
		
		TBuf8<1024> buf;
		if(iRouteTabViewArray.Count() > aIndex && iRouteTabViewArray[aIndex])
			buf.Copy( *iRouteTabViewArray[aIndex]->iCustomMessage );
		else
			StoreCustomMessageParamL(buf, _L8("curitin"), _L8("%d"), aIndex);

		if( viewId.iViewUid.iUid == ESingaporeBusRouteViewId )
			ActivateLocalViewL(TUid::Uid(ESingaporeBusRouteViewId2), TUid::Uid(0), buf);
		else
			ActivateLocalViewL(TUid::Uid(ESingaporeBusRouteViewId), TUid::Uid(0), buf);
		
		}
	else if (iListTabDecorator)
		{

		// if we arrive to the list tab from the route tab, and if we change tab in the list tab --> we are back to the top level
		for(TInt i = 0 ; i < iBackViewQueue.Count() ; ++i)
			delete iBackViewQueue[i];
		iBackViewQueue.Reset();

		TBuf8<1024> buf;
		switch(aIndex)
			{
			case 0:
				if( iListTabViewArray.Count() > aIndex && iListTabViewArray[aIndex] )
					buf.Copy( *iListTabViewArray[aIndex]->iCustomMessage );
				ActivateLocalViewL(TUid::Uid(ESingaporeBusStopsViewId), TUid::Uid(0), buf);
				break;
			case 1:
				if( iListTabViewArray.Count() > aIndex && iListTabViewArray[aIndex])
					buf.Copy( *iListTabViewArray[aIndex]->iCustomMessage );
				ActivateLocalViewL(TUid::Uid(ESingaporeBusServicesViewId), TUid::Uid(0), buf);
				break;
			default:
				{
				TVwsViewId viewId;
				GetActiveViewId(viewId);
				
				if(iFavoritesTabViewArray.Count() > aIndex - 2 && iFavoritesTabViewArray[aIndex - 2])
					buf.Copy( *iFavoritesTabViewArray[aIndex - 2]->iCustomMessage );
				else
					StoreCustomMessageParamL(buf, _L8("id"), _L8("%d"), aIndex - 2);

				if( viewId.iViewUid.iUid == ESingaporeBusFavoritesViewId )
					ActivateLocalViewL(TUid::Uid(ESingaporeBusFavoritesViewId2), TUid::Uid(0), buf);
				else
					ActivateLocalViewL(TUid::Uid(ESingaporeBusFavoritesViewId), TUid::Uid(0), buf);

				break;
				}
			}
		}
	}

#define KAknSplitInputEnabled   0x2001E2C0
#define KAknSplitInputDisabled  0x2001E2C1

struct CNewFavoritePaneDialog : public CAknDialog
	{
	TDes& iText;
	TBool iAknSplitInputEnabled;
	CNewFavoritePaneDialog(TDes& aDes) : iText(aDes) { }
	void PreLayoutDynInitL()
		{
    	CAknQueryControl* control = static_cast<CAknQueryControl*>(Control(ENewFavoritesPaneDataQuery));
    	CEikEdwin* edwin = (CEikEdwin*)control->ControlByLayoutOrNull(EMultiDataFirstEdwin);
    	edwin->SetAknEditorFlags( edwin->AknEdwinFlags() | EAknEditorFlagEnablePartialScreen );
    	edwin->SetTextL(&iText);
		}
    virtual TBool OkToExitL(TInt aButtonId)
    	{
    	CAknQueryControl* control = static_cast<CAknQueryControl*>(Control(ENewFavoritesPaneDataQuery));
    	CEikEdwin* edwin = (CEikEdwin*)control->ControlByLayoutOrNull(EMultiDataFirstEdwin);
    	edwin->GetText(iText);
    	return CEikDialog::OkToExitL(aButtonId);
    	}
    virtual void SetSizeAndPosition(const TSize& aSize)
    	{
    	CAknDialog::SetSizeAndPosition(aSize);
    	
    	if(iAknSplitInputEnabled)
    		{
			SetPosition(
					TPoint(
							Position().iX,0
							)
						);
			}
    	}
    virtual void HandleResourceChange(TInt aType)
    	{
    	TFunTrace funTrace(__PRETTY_FUNCTION__);
    	if ( aType == KAknSplitInputEnabled )
    		iAknSplitInputEnabled = ETrue;
    	else if ( aType == KAknSplitInputDisabled )
    		iAknSplitInputEnabled = EFalse;
    	CAknDialog::HandleResourceChange(aType);
    	}
    
	};

void CSingaporeBusAppUi::HandleForegroundEventL(TBool aForeground)
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();
	CAknViewAppUi::HandleForegroundEventL(aForeground);
	doc->HandleForegroundEventL(aForeground);
	}

/**
 * Handle a command for this appui (override)
 * @param aCommand command id to be handled
 */
void CSingaporeBusAppUi::HandleCommandL( TInt aCommand )
	{
TFunTrace funTrace(__PRETTY_FUNCTION__);
	// [[[ begin generated region: do not modify [Generated Code]
	TBool commandHandled = EFalse;
	switch ( aCommand )
		{ // code to dispatch to the AppUi's menu and CBA commands is generated here
		default:
			break;
		}
	
		
	if ( !commandHandled ) 
		{
		if ( aCommand == EAknSoftkeyExit || aCommand == EEikCmdExit )
			{
			Exit();
			}
		}
	// ]]] end generated region [Generated Code]
	
	CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();
	switch(aCommand)
		{
		case ESingaporeBusNewFavoritePane:
			{
			
			TBuf<128> paneName;
			CAknTextQueryDialog* dialog = CAknTextQueryDialog::NewL(paneName,CAknQueryDialog::ENoTone);
			dialog->PrepareLC(R_PANE_NAME_DIALOG);
			if(dialog->RunLD())
				{
				doc->CreateFavoritePaneL(paneName);
				HideTabGroup(); // force recreation of the tab group
				ShowListTabGroup( 2 + doc->iFavoritesTitles.Count() - 1 );
				TabChangedL( 2 + doc->iFavoritesTitles.Count() - 1 );
				}
			
			if(1==0)
				{
				TBuf<128> newFavoritePaneName;
				CAknDialog* dialog = new (ELeave) CNewFavoritePaneDialog(newFavoritePaneName);
				if( dialog->ExecuteLD(R_NEW_FAVORITES_PANE) )
					{
					doc->CreateFavoritePaneL(newFavoritePaneName);
					HideTabGroup(); // force recreation of the tab group
					ShowListTabGroup( 2 + doc->iFavoritesTitles.Count() - 1 );
					TabChangedL( 2 + doc->iFavoritesTitles.Count() - 1 );
					}
				}
			}
			break;
			
		case ESingaporeBusRenameFavoritePane:
			{
			TVwsViewId viewId;
			GetActiveViewId(viewId);
			if( viewId.iViewUid.iUid == ESingaporeBusFavoritesViewId || viewId.iViewUid.iUid == ESingaporeBusFavoritesViewId2 )
				{
				CSingaporeBusFavoritesView* view = (CSingaporeBusFavoritesView*)View( viewId.iViewUid );
				
				TBuf<128> paneName= *doc->iFavoritesTitles[view->iCurrentFavorite];
				CAknTextQueryDialog* dialog = CAknTextQueryDialog::NewL(paneName,CAknQueryDialog::ENoTone);
				dialog->PrepareLC(R_PANE_NAME_DIALOG);
				if(dialog->RunLD())
					{
					doc->RenameFavoritePaneL(view->iCurrentFavorite, paneName);
					TabCallbackL(); // force title refresh
					}
				

				if(1 == 0)
					{
					TBuf<128> newFavoritePaneName = *doc->iFavoritesTitles[view->iCurrentFavorite];
					CAknDialog* dialog = new (ELeave) CNewFavoritePaneDialog(newFavoritePaneName);
					if( dialog->ExecuteLD(R_NEW_FAVORITES_PANE) )
						{
						doc->RenameFavoritePaneL(view->iCurrentFavorite, newFavoritePaneName);
						TabCallbackL(); // force title refresh
						}
					}
				}
			}
			break;
			
		case ESingaporeBusDeleteFavoritePane:
			{
			TVwsViewId viewId;
			GetActiveViewId(viewId);
			if( viewId.iViewUid.iUid == ESingaporeBusFavoritesViewId || viewId.iViewUid.iUid == ESingaporeBusFavoritesViewId2 )
				{
				CSingaporeBusFavoritesView* view = (CSingaporeBusFavoritesView*)View( viewId.iViewUid );
				doc->DeleteFavoritePaneL(view->iCurrentFavorite);
				HideTabGroup(); // force recreation of the tab group
				ShowListTabGroup( 2 + doc->iFavoritesTitles.Count() - 1 );
				TabChangedL( 2 + doc->iFavoritesTitles.Count() - 1 );
				}
			}
			break;
			
		case ESingaporeBusSettings:
			{
			ActivateLocalViewL(TUid::Uid(ESingaporeBusSettingItemListViewId));
			break;
			}
			
		case EAknSoftkeyBack:
			{
			
			iBackCommand = ETrue;
			if(iBackViewQueue.Count() > 0)
				{
				CBackViewQueueItem* item = iBackViewQueue[iBackViewQueue.Count() - 1];
				
				//TBuf8<128> message;
				//message.Format(_L8("%d"), reinterpret_cast<TInt>(item->iCustomInfo));
				//ActivateLocalViewL(item->iViewId, item->iCustomMessageId, message);
				ActivateLocalViewL(item->iViewId, item->iCustomMessageId, *item->iCustomMessage);
				iBackViewQueue.Remove(iBackViewQueue.Count()-1);
				delete item;
				}
			else
				{
				HandleCommandL(EEikCmdExit);
				/*TVwsViewId viewId;
				if(GetDefaultViewId(viewId) == KErrNone)
					ActivateLocalViewL(viewId.iViewUid);*/
				}
			break;
			}
		}
	
	}

#define KAknSplitInputEnabled   0x2001E2C0
#define KAknSplitInputDisabled  0x2001E2C1
/** 
 * Override of the HandleResourceChangeL virtual function
 */
void CSingaporeBusAppUi::HandleResourceChangeL( TInt aType )
	{
TFunTrace funTrace(__PRETTY_FUNCTION__);
	CAknViewAppUi::HandleResourceChangeL( aType );
	// [[[ begin generated region: do not modify [Generated Code]
	// ]]] end generated region [Generated Code]
	}
				
/** 
 * Override of the HandleKeyEventL virtual function
 * @return EKeyWasConsumed if event was handled, EKeyWasNotConsumed if not
 * @param aKeyEvent 
 * @param aType 
 */
TKeyResponse CSingaporeBusAppUi::HandleKeyEventL(
		const TKeyEvent& aKeyEvent,
		TEventCode aType )
	{
TFunTrace funTrace(__PRETTY_FUNCTION__);
	// The inherited HandleKeyEventL is private and cannot be called
	// [[[ begin generated region: do not modify [Generated Contents]
	// ]]] end generated region [Generated Contents]
	
	if(iListTabDecorator || iRouteTabDecorator)
		{
		switch(aKeyEvent.iCode)
			{
			case EKeyLeftArrow: case EKeyRightArrow:
				{
				CAknTabGroup* tabGroup = ( CAknTabGroup* ) (iListTabDecorator ? iListTabDecorator : iRouteTabDecorator)->DecoratedControl();
				return tabGroup->OfferKeyEventL(aKeyEvent, aType);
				}
			}
		}

	return EKeyWasNotConsumed;
	}



static TInt ViewGroup(const TVwsViewId& aViewId)
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	switch(aViewId.iViewUid.iUid)
		{
			case ESingaporeBusStopsViewId:
			case ESingaporeBusServicesViewId:
			case ESingaporeBusFavoritesViewId:
			case ESingaporeBusFavoritesViewId2:
				return 1;
			case ESingaporeBusRouteViewId:
			case ESingaporeBusRouteViewId2:
				return 2;
			case EPublicTransportMapContainerViewId:
				return 3;
			case ESingaporeBusServicesArrivalTimeViewId:
				return 4;
			case ESingaporeBusServiceRouteViewId:
				return 5;
			default:
				return KErrNotFound;
		}
	
	}

/** 
 * Override of the HandleViewDeactivation virtual function
 *
 * @param aViewIdToBeDeactivated 
 * @param aNewlyActivatedViewId 
 */
void CSingaporeBusAppUi::HandleViewDeactivation( 
		const TVwsViewId& aViewIdToBeDeactivated, 
		const TVwsViewId& aNewlyActivatedViewId )
	{
TFunTrace funTrace(__PRETTY_FUNCTION__);
	CAknViewAppUi::HandleViewDeactivation( 
			aViewIdToBeDeactivated, 
			aNewlyActivatedViewId );
	// [[[ begin generated region: do not modify [Generated Contents]
	// ]]] end generated region [Generated Contents]
	
	
	iNewlyActivatedViewId = aNewlyActivatedViewId;
	
	
	
	if(
			iNewlyActivatedViewId.iAppUid == Application()->AppDllUid() &&
			aViewIdToBeDeactivated.iAppUid == Application()->AppDllUid() &&
			!iBackCommand &&
			ViewGroup(aViewIdToBeDeactivated) != ViewGroup(aNewlyActivatedViewId))
		{
		CStoreViewState* storeView = NULL;
		CCoeControl* container = NULL;
		switch(aViewIdToBeDeactivated.iViewUid.iUid)
			{
			case ESingaporeBusStopsViewId:
				storeView = (CSingaporeBusStopsView*)View(aViewIdToBeDeactivated.iViewUid);
				container = ((CSingaporeBusStopsView*)View(aViewIdToBeDeactivated.iViewUid))->iContainer.Get();
				break;
			case ESingaporeBusServicesViewId:
				storeView = (CSingaporeBusServicesView*)View(aViewIdToBeDeactivated.iViewUid);
				container = ((CSingaporeBusServicesView*)View(aViewIdToBeDeactivated.iViewUid))->iContainer.Get();
				break;
			case ESingaporeBusFavoritesViewId:
			case ESingaporeBusFavoritesViewId2:
				storeView = (CSingaporeBusFavoritesView*)View(aViewIdToBeDeactivated.iViewUid);
				container = ((CSingaporeBusFavoritesView*)View(aViewIdToBeDeactivated.iViewUid))->iContainer.Get();
				break;
			case ESingaporeBusRouteViewId:
			case ESingaporeBusRouteViewId2:
				storeView = (CSingaporeBusRouteView*)View(aViewIdToBeDeactivated.iViewUid);
				container = ((CSingaporeBusRouteView*)View(aViewIdToBeDeactivated.iViewUid))->iContainer.Get();
				break;
			case ESingaporeBusServicesArrivalTimeViewId:
				storeView = (CSingaporeBusServicesArrivalTimeView*)View(aViewIdToBeDeactivated.iViewUid);
				container = ((CSingaporeBusServicesArrivalTimeView*)View(aViewIdToBeDeactivated.iViewUid))->iContainer.Get();
				break;
			case ESingaporeBusServiceRouteViewId:
				storeView = (CSingaporeBusServiceRouteView*)View(aViewIdToBeDeactivated.iViewUid);
				container = ((CSingaporeBusServiceRouteView*)View(aViewIdToBeDeactivated.iViewUid))->iContainer.Get();
				break;
			case EPublicTransportMapContainerViewId:
				storeView = (CPublicTransportMapContainerView*)View(aViewIdToBeDeactivated.iViewUid);
				container = ((CPublicTransportMapContainerView*)View(aViewIdToBeDeactivated.iViewUid))->iContainer();
				break;
			}
		if(storeView && container)
			{
			TBuf8<1024> buf;
			storeView->StoreViewStateL(buf);
			LCleanedupPtr<CBackViewQueueItem> item ( new (ELeave) CBackViewQueueItem );
			item->iViewId = aViewIdToBeDeactivated.iViewUid;
			item->iCustomMessageId = TUid::Uid(0);
			item->iCustomInfo = NULL;
			item->iCustomMessage = buf.AllocL();
			iBackViewQueue.AppendL(item.Unmanage());
			}
		}
	iBackCommand = EFalse;
	
	iTabCallback->Cancel();
	iTabCallback->CallBack();
	
		
	}



/**
 * @brief Completes the second phase of Symbian object construction. 
 * Put initialization code that could leave here. 
 */ 
void CSingaporeBusAppUi::ConstructL()
	{
TFunTrace funTrace(__PRETTY_FUNCTION__);
	// [[[ begin generated region: do not modify [Generated Contents]
	
	BaseConstructL( EAknEnableSkin ); 
	InitializeContainersL();
	// ]]] end generated region [Generated Contents]

	{
	CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();
	doc->iSingaporeBusDrawItemsSG = new (ELeave) CSingaporeBusDrawItemsSG;
	doc->iSingaporeBusDrawItemsLD = new (ELeave) CSingaporeBusDrawItemsLD;
	doc->iSingaporeBusDrawItemsSG->ConstructL();
	doc->iSingaporeBusDrawItemsLD->ConstructL();
	}

	
	iSingaporeBusServicesView = CSingaporeBusServicesView::NewL();
	AddViewL( iSingaporeBusServicesView );

	iSingaporeBusStopsView = CSingaporeBusStopsView::NewL();
	AddViewL( iSingaporeBusStopsView );

	SetDefaultViewL( *iSingaporeBusStopsView );
	
	iSingaporeBusServicesArrivalTimeView = CSingaporeBusServicesArrivalTimeView::NewL();
	AddViewL( iSingaporeBusServicesArrivalTimeView );
	
	iSingaporeBusServiceRouteView = CSingaporeBusServiceRouteView::NewL();
	AddViewL( iSingaporeBusServiceRouteView );
	
	iSingaporeBusRouteView = CSingaporeBusRouteView::NewL();
	AddViewL( iSingaporeBusRouteView );
	
	iSingaporeBusRouteView2 = CSingaporeBusRouteView::NewL();
	iSingaporeBusRouteView2->iId = ESingaporeBusRouteViewId2;
	AddViewL( iSingaporeBusRouteView2 );
	
	iSingaporeBusFavoritesView = CSingaporeBusFavoritesView::NewL();
	AddViewL( iSingaporeBusFavoritesView );
	
	iSingaporeBusFavoritesView2 = CSingaporeBusFavoritesView::NewL();
	iSingaporeBusFavoritesView2->iId = ESingaporeBusFavoritesViewId2;
	AddViewL( iSingaporeBusFavoritesView2 );
	
	iTabCallback = new (ELeave) CAsyncCallBack( TCallBack(&MemFunDelegate<CSingaporeBusAppUi, &CSingaporeBusAppUi::TabCallbackL>, this), CActive::EPriorityIdle);
	iBackCommand = EFalse;

	
	GetDefaultViewId(iNewlyActivatedViewId);
	iTabCallback->Cancel();
	iTabCallback->CallBack();

		
	}

void CSingaporeBusAppUi::NotifyPositionChange()
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	GetActiveViewId(iNewlyActivatedViewId);
	TabCallbackL();
	}


void CSingaporeBusAppUi::NotifyJourneyPlannerQueryAnswerL()
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	GetActiveViewId(iNewlyActivatedViewId);
	TabCallbackL();
	}

TInt CSingaporeBusAppUi::TabCallbackL()
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	if(iNewlyActivatedViewId.iAppUid == Application()->AppDllUid())
		{
		CSingaporeBusDocument* doc = (CSingaporeBusDocument*)CEikonEnv::Static()->EikAppUi()->Document();
		CAknTitlePane* title = static_cast< CAknTitlePane* >( StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) );
		TBuf<128> titleBuf;
		switch(iNewlyActivatedViewId.iViewUid.iUid)
			{
			case ESingaporeBusStopsViewId:
				ShowListTabGroup(0);
				titleBuf.Format( _L("Stops") );
				break;
			case ESingaporeBusServicesViewId:
				ShowListTabGroup(1);
				titleBuf.Format( _L("Services") );
				break;
			case ESingaporeBusFavoritesViewId:
			case ESingaporeBusFavoritesViewId2:
				{
				CSingaporeBusFavoritesView* newlyActivatedView = (CSingaporeBusFavoritesView*)View(iNewlyActivatedViewId.iViewUid);
				ShowListTabGroup(2 + newlyActivatedView->iCurrentFavorite);
				titleBuf.Format( *doc->iFavoritesTitles[newlyActivatedView->iCurrentFavorite] );
				}
				break;
			case ESingaporeBusRouteViewId:
			case ESingaporeBusRouteViewId2:
				{
				if(doc->iJourneyPlannerOutput && doc->iJourneyPlannerOutput->iItineraries.Count())
					{
					CSingaporeBusRouteView* newlyActivatedView = (CSingaporeBusRouteView*)View(iNewlyActivatedViewId.iViewUid);
					ShowRouteTabGroup(newlyActivatedView->iCurrentItinerary);
					titleBuf.Format(_L("Solution %d"), newlyActivatedView->iCurrentItinerary+1);
					}
				else
					{
					HideTabGroup();
					titleBuf.Format( KNullDesC() );
					}
				}
				break;
			case ESingaporeBusServicesArrivalTimeViewId:
				{
				TInt tabIndex = 0;
				if(	iBackViewQueue.Count() > 0)
					{
					CBackViewQueueItem* item = iBackViewQueue[iBackViewQueue.Count() - 1];
					if(item->iViewId.iUid == ESingaporeBusFavoritesViewId || item->iViewId.iUid == ESingaporeBusFavoritesViewId2)
						{
						TPtrC8 field, value, remainder(*item->iCustomMessage);
						while(ParseCustomMessageParamL(field, value, remainder))
							{
							if(field == _L8("id"))
								{
								TInt id;
								TLex8 lex(value);
								lex.Val(id);
								tabIndex = 2 + id;
								}
							}
						}
					}
				ShowListTabGroup(tabIndex);
				CSingaporeBusServicesArrivalTimeView* newlyActivatedView = (CSingaporeBusServicesArrivalTimeView*)View(iNewlyActivatedViewId.iViewUid);
				if(newlyActivatedView->iSelectedStation->iStationType == TStation::ELDNormal)
					{
					titleBuf.Format(_L("%S"), narrowToWideLC(newlyActivatedView->iSelectedStation->iAddress2));
					CleanupStack::PopAndDestroy();
					if(newlyActivatedView->iSelectedStation->iAddress.Length())
						{
						titleBuf.AppendFormat(_L(" - Towards %S"), narrowToWideLC(newlyActivatedView->iSelectedStation->iAddress));
						CleanupStack::PopAndDestroy();
						}
					}
				else
					{
					titleBuf.Format(_L("%S - %S"), narrowToWideLC(newlyActivatedView->iSelectedStation->iAddress2), narrowToWideLC(newlyActivatedView->iSelectedStation->iAddress));
					CleanupStack::PopAndDestroy(2);
					}
				break;
				}
			case ESingaporeBusServiceRouteViewId:
				{
				ShowListTabGroup(1);
				CSingaporeBusServiceRouteView* newlyActivatedView = (CSingaporeBusServiceRouteView*)View(iNewlyActivatedViewId.iViewUid);
				titleBuf.Format(_L("%S to %S"), narrowToWideLC(newlyActivatedView->iSelectedService->iName), narrowToWideLC(newlyActivatedView->iSelectedService->iTo));
				CleanupStack::PopAndDestroy(2);
				break;
				}
			default:
				HideTabGroup();
				break;
			}
		if(titleBuf.Length())
			{
			titleBuf.AppendFormat( _L("\n(%S)"), &doc->PositionDescription() );
			title->SetTextL( titleBuf );
			title->DrawDeferred();
			//static_cast<CAknNaviLabel*>(iNaviDecorator_->DecoratedControl())->DrawDeferred();
			}
		}
		}

void CSingaporeBusAppUi::SwitchCustomLayout1(CEikStatusPane* aStatusPane)
	{
	TFunTrace funTrace(__PRETTY_FUNCTION__);
	
	if(aStatusPane->PaneCapabilities( TUid::Uid( EEikStatusPaneUidContext ) ).IsInCurrentLayout())
		{
			CCoeControl* titlePane = aStatusPane->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) );
			CCoeControl* naviPane = aStatusPane->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) );
			CCoeControl* contextPane = aStatusPane->ControlL( TUid::Uid( EEikStatusPaneUidContext ) );
			RDrawableWindow* titleWin = titlePane->DrawableWindow();	
			RDrawableWindow* naviWin = naviPane->DrawableWindow();
			RDrawableWindow* contextWin = contextPane->DrawableWindow();
			TRect contextRect( contextWin->Position(), contextWin->Size() );
			TRect naviRect( naviWin->Position(), naviWin->Size() );
			TRect titleRect( titleWin->Position(), titleWin->Size() );
			if(contextRect.iTl.iX < titleRect.iTl.iX)
				{
				titleRect.iTl.iX = contextRect.iTl.iX;
				titleWin->SetExtentErr(titleRect.iTl, titleRect.Size());
				titlePane->SetRect( TRect(TPoint(0,0),titleRect.Size()) );
				}
			if(contextRect.iTl.iX < naviRect.iTl.iX)
				{
				naviRect.iTl.iX = contextRect.iTl.iX;
				naviWin->SetExtentErr(naviRect.iTl, naviRect.Size());
				naviPane->SetRect( TRect(TPoint(0,0),naviRect.Size()) );
				}		
		}		
	}



// [[[ begin generated function: do not modify
/**
 * Show the popup dialog for recomputeRouteQuery
 * @param aOverrideText optional override text
 * @return EAknSoftkeyYes (left soft key id) or 0
 */
TInt CSingaporeBusAppUi::RunRecomputeRouteQueryL( const TDesC* aOverrideText )
	{
				
	CAknQueryDialog* queryDialog = CAknQueryDialog::NewL();	
	
	if ( aOverrideText != NULL )
		{
		queryDialog->SetPromptL( *aOverrideText );
		}
	return queryDialog->ExecuteLD( R_APPLICATION_RECOMPUTE_ROUTE_QUERY );
	}
// ]]] end generated function

// [[[ begin generated function: do not modify
/**
 *	Create a list box item with the given column values.
 */
void CSingaporeBusAppUi::CreateSelectTravelOptionQueryItemL( 
		TDes& aBuffer, 
		
		const TDesC& aMainText )
	{
	_LIT ( KStringHeader, "%S" );

	aBuffer.Format( KStringHeader(), &aMainText );
	}
// ]]] end generated function

// [[[ begin generated function: do not modify
/**
 *	Add an item to the list by reading the text items from resource
 *	and setting a single image property (if available) from an index
 *	in the list box's icon array.
 *	@param aResourceId id of an ARRAY resource containing the textual
 *	items in the columns
 *	
 */
void CSingaporeBusAppUi::CreateSelectTravelOptionQueryResourceArrayItemL( 
		TDes& aBuffer, 
		TInt aResourceId )
	{
	CDesCArray* array = CCoeEnv::Static()->ReadDesCArrayResourceL( aResourceId );
	CleanupStack::PushL( array );
	CreateSelectTravelOptionQueryItemL( aBuffer, ( *array ) [ 0 ] );
	CleanupStack::PopAndDestroy( array );
	}
// ]]] end generated function

// [[[ begin generated function: do not modify
/**
 * Initialize contents of the popup item list.  This constructs the array
 *	and pushes it on the cleanup stack.
 *	@return item array, never null
 */
CDesCArray* CSingaporeBusAppUi::InitializeSelectTravelOptionQueryLC()
	{
	const int KNumItems = 2;
	CDesCArray* itemArray = new ( ELeave ) CDesCArrayFlat( KNumItems ? KNumItems : 1 );
	CleanupStack::PushL( itemArray );
	
	// This is intended to be large enough, but if you get 
	// a USER 11 panic, consider reducing string sizes.
	TBuf< 512 > des;
	CreateSelectTravelOptionQueryResourceArrayItemL(
			des, R_APPLICATION_LISTBOX_ITEM1 );
	itemArray->AppendL( des );
	CreateSelectTravelOptionQueryResourceArrayItemL(
			des, R_APPLICATION_LISTBOX_ITEM2 );
	itemArray->AppendL( des );
	return itemArray;
	}
// ]]] end generated function

// [[[ begin generated function: do not modify
/**
 *	Set up the list query's icon array.  If any icons are used, allocates an
 *	icon array, and places it on the cleanup stack. 
 *	@return icon array, or NULL
 */
CArrayPtr< CGulIcon >* CSingaporeBusAppUi::SetupSelectTravelOptionQueryIconsLC()
	{
	CArrayPtr< CGulIcon >* icons = NULL;
	return icons;
	}
	
// ]]] end generated function

// [[[ begin generated function: do not modify
/**
 * Show the popup list query dialog for selectTravelOptionQuery.
 * <p>
 * You may override the designer-specified items or icons, though generally
 * both should be overridden together.
 * @param aOverrideText optional override text
 * @param aOverrideItemArray if not NULL, the array of formatted list items to display (passes ownership)
 * @param aOverrideIconArray if not NULL, the array of icons to display (passes ownership)
 * @return selected index (>=0) or -1 for Cancel
 */
TInt CSingaporeBusAppUi::RunSelectTravelOptionQueryL( 
		const TDesC* aOverrideText,
		CDesCArray* aOverrideItemArray,
		CArrayPtr< CGulIcon >* aOverrideIconArray )
	{
	TInt index = 0;
	CAknListQueryDialog* queryDialog = NULL;
	queryDialog = new ( ELeave ) CAknListQueryDialog( &index );	
	CleanupStack::PushL( queryDialog );
	
	queryDialog->PrepareLC( R_APPLICATION_SELECT_TRAVEL_OPTION_QUERY );
	if ( aOverrideText != NULL )
		{
		queryDialog->SetHeaderTextL( *aOverrideText );
		}
		
	// initialize list items
	CDesCArray* itemArray = NULL;
	
	if ( aOverrideItemArray != NULL ) 
		{
		CleanupStack::PushL( aOverrideItemArray );
		itemArray = aOverrideItemArray;
		}
	else
		{
		itemArray = InitializeSelectTravelOptionQueryLC();
		}
		
	queryDialog->SetItemTextArray( itemArray );
	queryDialog->SetOwnershipType( ELbmOwnsItemArray );
	CleanupStack::Pop( itemArray );
	
	// initialize list icons
	CArrayPtr< CGulIcon >* iconArray = NULL;
	
	if ( aOverrideIconArray != NULL )
		{
		CleanupStack::PushL( aOverrideIconArray );
		iconArray = aOverrideIconArray;
		}
	else
		{
		iconArray = SetupSelectTravelOptionQueryIconsLC();
		}
		
	if ( iconArray != NULL ) 
		{
		queryDialog->SetIconArrayL( iconArray );	// passes ownership
		CleanupStack::Pop( iconArray );
		}
	
	// run dialog
	TInt result = queryDialog->RunLD();
	
	// clean up
	CleanupStack::Pop( queryDialog );
	
	return result == 0 ? -1 : index;
	}
	
// ]]] end generated function

